package com.feilong.cn.mybatis.autoV2.config;

import com.feilong.cn.mybatis.autoV2.plugin.AutoInterceptor;
import com.feilong.cn.mybatis.autoV2.plugin.AutoInterceptorChain;
import com.feilong.cn.mybatis.autoV2.statement.MappedStatement;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.builder.IncompleteElementException;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yangxulong on 2018/4/2.
 */
public class AutoConfiguration {

    //用来模拟存储Mapper接口类, 以便读取Sql注解
    private List<String> scanClasses = new ArrayList<>();

    //key=namespace+方法名,
    private Map<String, MappedStatement> mappedStatementMap = new HashMap<>();
    private final AutoInterceptorChain interceptorChain = new AutoInterceptorChain();

    public AutoInterceptorChain getInterceptorChain(){
        return interceptorChain;
    }

    public void addScanClass(String strClass) {
        scanClasses.add(strClass);
    }


    public List<String> getScanClass() {
        return scanClasses;
    }

    //扫描scanClasses中的类, 初始化 mappedStatementMap
    public void initMappedStatement() throws ClassNotFoundException {
        for (String clazz : scanClasses) {
            if (!"".equals(clazz)) {
                Class claxx = Class.forName(clazz);
                if (claxx != null) {
                    addMappedStatement(claxx);
                }
            }
        }
    }

    public void addMappedStatement(Class clazz) {
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            try {
                if (!method.isBridge()) {
                    try {
                        String id = clazz.getName() + "." + method.getName();
                        if (mappedStatementMap.containsKey(id)) {
                            return;
                        }

                        Annotation selectA = method.getAnnotation(Select.class);
                        if (selectA == null) {
                            return;
                        }
                        //从注解中提取Sql语句, 并存在MappedStatement对象中.
                        final String[] strings = (String[]) selectA.getClass().getMethod("value").invoke(selectA);
                        MappedStatement satement = new MappedStatement(id, strings[0], method.getReturnType());
                        this.mappedStatementMap.put(id, satement);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (IncompleteElementException e) {
                e.printStackTrace();
            }
        }
    }

    public MappedStatement getMappedStatement(String id) {
        return (MappedStatement) mappedStatementMap.get(id);
    }

    public void addInterceptor(AutoInterceptor interceptor) {
        this.interceptorChain.addInterceptor(interceptor);
    }

}
